Developer.com Click here to support our advertisers
Click here to support our advertisers
SOFTWARE FOR SALE
BOOKS FOR SALE
SEARCH CENTRAL
*JOB BANK
*CLASSIFIEDS
*DIRECTORIES
*REFERENCE
Online Library
*LEARNING CENTER
*JOURNAL
*NEWS CENTRAL
*DOWNLOADS
*COMMUNITY
*CALENDAR
*ABOUT US
-----
Journal:

Get the weekly email highlights from the most popular journal for developers!
Current issue -----
developer.com
developerdirect.com
htmlgoodies.com
javagoodies.com
jars.com
intranetjournal.com
javascripts.com

REFERENCE

All Categories : C/C++

vclp11.htm



- Project 11 -
Inheritance and Virtual Functions


In this lesson, you learned about the advanced features of Visual C++. You learned how to make one class out of another and how to change the way a function is called to depend on either the calling type or the object type.

In this lesson, you saw the following:

  • Deriving a class

  • Access to class members under derivation

  • Calling constructors and destructors of base classes

  • Calling the correct version of an overridden function

  • Declaring a member function to be virtual

  • How virtual functions are called depending on the type of the object.

Project 11 Listing. An object-oriented pet care program.


  1:// File name : PROJCT11.CPP

  2:// Object oriented pet program to manage

  3:// a simple list of different types of

  4:// pets

  5://

  6:#include <iostream.h>

  7:#include <string.h>

  8:

  9://------------------------------------------------------------

 10:// Pet class

 11://

 12:class Pet

 13:  {

 14:    public:

 15:      virtual ~Pet()              // Destructor

 16:        {

 17:          delete [] name;

 18:        }

 19:      void Print() const;         // Print all about pet

 20:      void Query();               // Get details

 21:      const char * GetName() const// Provide name string

 22:        {

 23:          if (name)

 24:            return name;

 25:          else

 26:            return "";

 27:        }

 28:    protected:

 29:      virtual void PrintDetails() const = 0;// Print details

 30:      virtual void QueryDetails() = 0;      // Ask for details

 31:      virtual const char * GetPetType() const = 0;

 32:      Pet()     // protected -

 33:                // do not make Pets

 34:        {

 35:          name = 0;

 36:        }

 37:    private:

 38:      char * name;

 39:  };

 40:void Pet::Print() const

 41:  {

 42:    cout << GetPetType()  << " : ";

 43:    if (name)

 44:      cout << name << " - ";

 45:    PrintDetails();

 46:    cout << endl;

 47:  }

 48:

 49:void Pet::Query()

 50:  {

 51:    char tempName[81];

 52:    cout << "What is your pet " << GetPetType() <<"'s name? ";

 53:    cin.getline(tempName,81);

 54:    if (name)

 55:      delete [] name;

 56:    name = new char[strlen(tempName) + 1];

 57:    strcpy(name,tempName);

 58:    QueryDetails();

 59:  }

 60:

 61://------------------------------------------------------------

 62:// Cat class - derived from Pet

 63://

 64:class Cat : public Pet

 65:  {

 66:    public:

 67:      Cat(int Scratches = 1)

 68:        {

 69:          scratches = Scratches;

 70:        }

 71:    protected:

 72:      virtual void PrintDetails() const;

 73:      virtual void QueryDetails();

 74:      const char * GetPetType() const

 75:        {

 76:          return "Cat";

 77:        }

 78:    private:

 79:      int scratches;

 80:  };

 81:

 82:void Cat::PrintDetails() const

 83:  {

 84:    cout << "Scratches: " << (scratches? "Yes":"No");

 85:  }

 86:

 87:void Cat::QueryDetails()

 88:  {

 89:    char yn;

 90:    cout << "Does your cat " << GetName() << " scratch? ";

 91:    cin >> yn;

 92:    cin.ignore(80,'\n');

 93:    if (yn == 'Y' || yn == 'y')

 94:      scratches = 1;

 95:    else

 96:      scratches = 0;

 97:  }

 98:

 99://------------------------------------------------------------

100:// Dog class - derived from Pet

101://

102:

103:class Dog : public Pet

104:  {

105:    public:

106:      Dog(int Barks = 1)

107:        {

108:          barks = Barks;

109:        }

110:    protected:

111:      virtual void PrintDetails() const;

112:      virtual void QueryDetails();

113:      const char * GetPetType() const

114:        {

115:          return "Dog";

116:        }

117:    private:

118:      int barks;

119:  };

120:

121:void Dog::PrintDetails() const

122:  {

123:    cout << "Barks: " << (barks? "Yes":"No");

124:  }

125:

126:void Dog::QueryDetails()

127:  {

128:    char yn;

129:    cout << "Does your dog " << GetName() << " bark? ";

130:    cin >> yn;

131:    cin.ignore(80,'\n');

132:    if (yn == 'Y' || yn == 'y')

133:      barks = 1;

134:    else

135:      barks = 0;

136:  }

137:

138://------------------------------------------------------------

139:// Fish class - derived from Pet

140://

141:class Fish : public Pet

142:  {

143:    public:

144:      Fish(int ColdWater = 0)

145:        {

146:          coldWater = ColdWater;

147:        }

148:    protected:

149:      virtual void PrintDetails() const;

150:      virtual void QueryDetails();

151:      const char * GetPetType() const

152:        {

153:          return "Fish";

154:        }

155:    private:

156:      int coldWater;

157:  };

158:void Fish::PrintDetails() const

159:  {

160:    cout << (coldWater? "Cold water":"Tropical");

161:  }

162:

163:void Fish::QueryDetails()

164:  {

165:    char yn;

166:    cout << "Is your fish " << GetName() << " tropical? ";

167:    cin >> yn;

168:    cin.ignore(80,'\n');

169:    if (yn == 'Y' || yn == 'y')

170:      coldWater = 0;

171:    else

172:      coldWater = 1;

173:  }

174:

175://------------------------------------------------------------

176:// main procedure

177://

178:

179:void main()

180:  {

181:     const int maxPets = 20;

182:     char type = ' ';

183:     Pet * pets[maxPets] = {0};

184:     int count = 0;

185:

186:     while (count < maxPets)

187:       {

188:         // Where do you want to go today?

189:         cout << "Pet type, [C]at, [D]og, [F]ish, [Q]uit: ";

190:         cin >> type;

191:         cin.ignore(80,'\n');

192:

193:         // Stop loop early

194:         if (type == 'q' || type == 'Q')

195:           break;

196:

197:         switch (type)

198:           {

199:             case 'C': // Cat

200:             case 'c':

201:               {

202:                 pets[count] = new Cat;

203:                 break;

204:               }

205:             case 'D': // Dog

206:             case 'd':

207:               {

208:                 pets[count] = new Dog;

209:                 break;

210:               }

211:             case 'F': // Fish

212:             case 'f':

213:               {

214:                 pets[count] = new Fish;

215:                 break;

216:               }

217:             default:

218:               continue; // can be used in switch

219:          }

220:        pets[count]->Query();

221:        count++;

222:      }

223:

224:   // List pets - don't need derived classes for this

225:    cout << endl << "Pet Names" << endl;

226:    for (int i = 0; i < count; i++)

227:      {

228:        cout << pets[i]->GetName();

229:        cout << endl;

230:      }

231:

232:    // Print characteristics - rely on virtual functions

233:    cout << endl << "Characteristics" << endl;

234:    for (i = 0; i < count; i++)

235:      pets[i]->Print();

236:

237:    // Tidy up storage

238:    for (i = 0; i < count; i++)

239:      delete pets[i];

240:  }

OUTPUT

      
      Pet type, [C]at, [D]og, [F]ish, [Q]uit: cat
      
      What is your pet Cat's name? Tibbles
      
      Does your cat Tibbles scratch? no, never has
      
      Pet type, [C]at, [D]og, [F]ish, [Q]uit: d
      
      What is your pet Dog's name? Ross
      
      Does your dog Ross bark? Yes
      
      Pet type, [C]at, [D]og, [F]ish, [Q]uit: f
      
      What is your pet Fish's name? Wanda
      
      Is your fish Wanda tropical? yes
      
      Pet type, [C]at, [D]og, [F]ish, [Q]uit: p
      
      Pet type, [C]at, [D]og, [F]ish, [Q]uit: q
      
      Pet Names
      
      Tibbles
      
      Ross
      
      Wanda
      
      Characteristics
      
      Cat : Tibbles - Scratches: No
      
      Dog : Ross - Barks: Yes
      
      Fish : Wanda - Tropical

Description

1: Comment refers to the source filename.

2: Comment to describe the program.

3: The program description continues.

4: The program description continues.

5: Blank lines help to make the program more readable.

6: Include the header for the library of stream output functions.

7: Include the header for the library of string handling functions.

8: Blank lines help to make the program more readable.

9: A comment helps separate the different classes.

10: A title for the following class.

11: A blank comment can also be used for appearance.

12: A line to declare a class called Pet.

13: All classes start with an opening brace.

14: All members after this label will be declared public.

15: The destructor for Pet is shown with the ~ character. It is declared virtual.

16: The destructor function is coded inline. The function starts with an opening brace.

17: Delete the character string pointed to by name.

18: All functions end with a closing brace.

19: A function Print() is declared that will not change the class members.

20: A function Query() is declared. This is allowed to change class members.

21: A function GetName() is declared that will not change class members.

22: All functions start with opening braces. This is declared inline.

23: name might not have a string attached, but the constructor ensures it is zeroed.

24: If name did have a string, return it.

25: A single statement if-else does not need braces surrounding the statement.

26: Return a blank string if no name has been set.

27: A closing brace ends all functions.

28: All members following this label will be protected.

29: This virtual function has not been defined and is known as a pure virtual function.

30: QueryDetails() is also a pure virtual function.

31: There is no definition for GetPetType().

32: The default constructor for the Pet class.

33: A comment helps explain an unusual coding feature.

34: An inline function starts with a closing brace.

35: Pointers should always be initialized. A valid pointer can never be zero.

36: Functions always end with closing braces.

37: All members following this label will be private.

38: A pointer to a character string initially does not own any storage.

39: All class declarations end with both a closing brace and a semicolon.

40: The function Print() belonging to the Pet class is defined.

41: All functions start with an opening brace.

42: Output the type of pet, using a virtual function so that each class can output its name.

43: Check the validity of a character pointer before using.

44: name is a member of this class, so it needs no special function to access it.

45: Call a virtual function to get details that differ by derived type.

46: Output a newline sequence.

47: All functions end with a closing brace.

48: Blank lines help you make the code more readable.

49: Define the nonvirtual function Query.

50: All functions start with an opening brace.

51: Declare a temporary character string much bigger than expected input.

52: Ask for user input, using a virtual function to customize the request for each class.

53: Get the name into a temporary string.

54: If the name already points at a string, delete it.

55: Delete the current string to recover the memory.

56: Create a dynamic memory allocation just big enough to hold the string and its terminator.

57: Copy the temporary name into the class storage.

58: Call a virtual function to get details specific to the actual class.

59: All functions end with a closing brace.

60: Blank lines help to make the program more readable.

61: A comment to mark the start of a new class.

62: A comment to identify which class is now being defined.

63: Empty comments can enhance the appearance of the program.

64: Class Cat builds the functionality of class Pet.

65: Class definitions start with an opening brace.

66: All members following this label will be public.

67: The constructor for cat can optionally take a parameter.

68: A function always starts with an opening brace.

69: A constructor should always initialize the members.

70: A function always ends with a closing brace.

71: All the functions following this label will be protected.

72: This class is going to define the PrintDetails() function.

73: This class is going to define the QueryDetails() function.

74: This class defines the GetPetType() function.

75: All functions start with an opening brace.

76: This function returns the literal string Cat.

77: All functions end with a closing brace.

78: All members following this label will be private.

79: A private data member that is an integer.

80: All class definitions end with a closing brace and a semicolon.

81: Blank lines make the program more readable.

82: Define the function PrintDetails(). This version belongs to Cat.

83: All functions start with an opening brace.

84: Output extra details of Cat class.

85: All functions end with a closing brace.

86: Blank lines help to make the program more readable.

87: Define the function QueryDetails().

88: All functions start with an opening brace.

89: Declare a character variable to test the input.

90: Query the user for information. Customize the output with a call for base class information.

91: Ask for an answer that takes just the first character.

92: Ignore the input up until the newline character.

93: If the answer is yes. . .

94: Set the member flag to true.

95: If the answer is no. . .

96: Set the member flag to false.

97: All functions end with a closing brace.

98: Blank lines help to make the program more readable.

99: A comment to mark the start of a new class.

100: A comment to identify which class is now being defined.

101: Empty comments can enhance the appearance of the program.

102: Blank lines help to make the program more readable.

103: Class Dog builds the functionality of class Pet.

104: Class definitions start with an opening brace.

105: All members following this label will be public.

106: The constructor for Dog can optionally take a parameter.

107: A function always starts with an opening brace.

108: A constructor should always initialize the members.

109: A function always ends with a closing brace.

110: All functions following this label will be protected.

111: This class is going to define the PrintDetails() function.

112: This class is going to define the QueryDetails() function.

113: This class defines the GetPetType() function.

114: All functions start with an opening brace.

115: This function returns the literal string Dog.

116: All functions end with a closing brace.

117: All members following this label will be private.

118: A private data member that is an integer.

119: All class definitions end with a closing brace and a semicolon.

120: Blank lines make the program more readable.

121: Define the function PrintDetails(). This version belongs to Cat.

122: All functions start with an opening brace.

123: Output extra details of Dog class.

124: All functions end with a closing brace.

125: Blank lines help to make the program more readable.

126: Define the function QueryDetails().

127: All functions start with an opening brace.

128: Declare a character variable to test the input.

129: Query the user for information. Customize the output with a call for base class information.

130: Ask for an answer that takes just the first character.

131: Ignore the input up until the newline character.

132: If the answer is yes. . .

133: Set the member flag to true.

134: If the answer is no. . .

135: Set the member flag to false.

136: All functions end with a closing brace.

137: Blank lines help to make the program more readable.

138: A comment to mark the start of a new class.

139: A comment to identify which class is now being defined.

140: Empty comments can enhance the appearance of the program.

141: Class Fish builds the functionality of class Pet.

142: Class definitions start with an opening brace.

143: All members following this label will be public.

144: The constructor for Fish can optionally take a parameter.

145: A function always starts with an opening brace.

146: A constructor should always initialize the members.

147: A function always ends with a closing brace.

148: All the functions following this label will be protected.

149: This class is going to define the PrintDetails() function.

150: This class is going to define the QueryDetails() function.

151: This class defines the GetPetType() function.

152: All functions start with an opening brace.

153: This function returns the literal string Fish.

154: All functions end with a closing brace.

155: All members following this label will be private.

156: A private data member that is an integer.

157: All class definitions end with a closing brace and a semicolon.

158: Define the function PrintDetails(). This version belongs to Fish.

159: All functions start with an opening brace.

160: Output extra details of Cat class.

161: All functions end with a closing brace.

162: Blank lines help to make the program more readable.

163: Define the function QueryDetails().

164: All functions start with an opening brace.

165: Declare a character variable to test the input.

166: Query the user for information. Customize the output with a call for base class information.

167: Ask for an answer that takes just the first character.

168: Ignore the input up until the newline character.

169: If the answer is yes. . .

170: Set the member flag to true.

171: If the answer is no. . .

172: Set the member flag to false.

173: All functions end with a closing brace.

174: Blank lines make the program more readable.

175: A comment to divide the code.

176: A comment to tell the programmer that he has found the main procedure.

177: Blank comments can enhance the appearance of the program.

178: Blank lines make the program more readable.

179: The start of the main procedure.

180: All functions start with an opening brace.

181: Define a constant for the maximum number of entries.

182: Initialize a temporary input character.

183: Define an array of pointers to the Pet class.

184: A counter to record how many pets have been entered.

185: Blank lines make the program more readable.

186: Do the following statements as long as the number of entries do not exceed the array capacity.

187: A while loop of multiple statements is delimited by an opening brace.

188: Not all comments serve a useful purpose.

189: Prompt the user for a selection.

190: Store the first character of a users answer.

191: Ignore any spare input after the first character.

192: Blank lines make the program more readable.

193: Comments can explain why code is written.

194: Test the input to see whether the user has finished.

195: Leave the loop if the if test is true.

196: Blank lines make the program more readable.

197: Avoid complex if statements by using the switch statement.

198: switch statements are enclosed in braces.

199: Execute from here if type is 'C'.

200: Execute from here if type is 'c'. The first case will fall through.

201: case statements can be enclosed in a block.

202: Make an object of type Cat and store it in a general Pet pointer.

203: Break out of the rest of the switch statement.

204: End of case block.

205: case for Dog.

206: case for Dog.

207: case statements can be enclosed in a block.

208: Make an object of type Dog and store it in a general Pet pointer.

209: Break out of the rest of the switch statement.

210: End of case block.

211: case for Fish

212: case for Fish

213: case statements can be enclosed in a block.

214: Make an object of type Fish and store it in a general Pet pointer.

215: Break out of the rest of the switch statement.

216: End of case block.

217: If the input does not match any planned case, do the following.

218: Executing continue will go around the loop, skipping the remaining code.

219: End the switch statement.

220: Call the input function for the new object. Because it contains virtual function calls, different code for each type will be called.

221: Increment the number of valid objects count.

222: End the while loop compound statement.

223: Blank lines help make the program more readable.

224: Comment to help understand the following processing.

225: Output a title.

226: for as many items in the container.

227: for loops performing multiple statements enclose them in braces.

228: Output the pet's name by using a nonvirtual function belonging to the base class.

229: A newline character sequence is output.

230: End of the for loop is denoted by the closing brace.

231: Blank lines make the program more readable.

232: A comment to explain the following processing.

233: Output a title.

234: for all the items in the container.

235: A for loop can execute a single statement.

236: Blank lines make the code more readable.

237: A comment to explain the following processing.

238: for each item in the container.

239: Delete the storage associated with the pointer.

240: The main function ends with a closing brace.



29: Classes containing pure virtual functions are known as abstract classes.

69: If no base constructor is explicitly called in the initialization list, the default base constructor is called.

71: Protected members are only visible to this class and derived classes.

76: Visual C++ can't access the actual class name.

183: An array of pointers takes up a small amount of space compared to the classes, and derived classes might take up much more storage than a base class.

201: case statements must be enclosed in braces if they declare a variable.

203: Meeting a case statement does not cause a branch out of the switch statement.

226: The scope of local variable i is the block containing for, not the for loop itself. Note the following for loops.

235: Print() contains virtual functions that will execute code specific to each object's class.

239: Because the base class destructor is virtual, the correct destructor will be called even though the pointer belongs to the base class.


Ruler image
Contact reference@earthweb.com with questions or comments.
Copyright 1998 EarthWeb Inc., All rights reserved.
PLEASE READ THE ACCEPTABLE USAGE STATEMENT.
Copyright 1998 Macmillan Computer Publishing. All rights reserved.

Click here for more info

Click here for more info